package nl.infodation.emr.pricingservice.controller;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import nl.infodation.emr.pricingservice.data.ProductSelection;
import nl.infodation.emr.psrefdata.entity.Item;
import nl.infodation.emr.utility.StringUtil;

import com.vaadin.data.util.BeanItem;

@SuppressWarnings({"deprecation", "rawtypes", "unchecked"})
public class ProductSelectionController extends AbstractBaseController<Object, ProductSelection, Integer> {

	public ProductSelectionController() {
		setEntityManagerFactoryForRole();
	}

	@Override
	public long getTotalNumberItemByCriteria(ProductSelection t) {
		long countResult = 0l;
		setEntityManagerFactoryForRole();
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			queryString.setLength(0);
			final ProductSelection p = (ProductSelection) t;

			buildSelectCount(new Item());
			buildQueryForProductSelection(p);

			final TypedQuery<Long> query = entityManager.createQuery(queryString
					.toString(), Long.class);
			LOG.info("Executing the query \"{}\".", queryString);
			countResult = query.getSingleResult();
		} catch (IllegalStateException ex) {
			LOG.error("Error reading getTotalNumberItemByCriteria", ex);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return countResult;
	}

	@Override
	public List getPaginationByCriteria(ProductSelection object, int startPage,
			int pageSize) {
		final List<BeanItem> beans = new ArrayList<BeanItem>();
		setEntityManagerFactoryForRolePopup(object.getBussines());
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();

			queryString.setLength(0);
			final ProductSelection p = (ProductSelection) object;

			buildSelect(new Item());
			buildQueryForProductSelection(p);

			final TypedQuery<Item> query = entityManager.createQuery(
					queryString.toString(), Item.class);
			if (startPage > 0) {
				query.setFirstResult((startPage - 1) * pageSize);
			} else {
				query.setFirstResult(1);
			}
			query.setMaxResults(pageSize);
			LOG.info("Executing the query \"{}\".", queryString);
			final List<Item> results = query.getResultList();
			if (!results.isEmpty()) {
				for (Item item : results) {
					ProductSelection productSelection = new ProductSelection();
					productSelection.setRefcoId(item.getProduct()
							.getCommercialReferences().getRefcoId());
					productSelection.setProductId(String.valueOf(item
							.getProduct().getProductId()));
					productSelection.setProductCode(item.getProduct()
							.getProductCode());
					productSelection
							.setItemId(String.valueOf(item.getItemId()));
					productSelection.setCountryCode(item
							.getProduct()
							.getCommercialReferences()
							.getOffer()
							.getSalesSupport()
							.getCountryCode());
					productSelection.setLanguageCode(item
							.getProduct()
							.getCommercialReferences()
							.getOffer()
							.getSalesSupport()
							.getLanguageCode());

					beans.add(new BeanItem<ProductSelection>(productSelection));
				}
			}
		} catch (IllegalStateException ex) {
			LOG.error("Error reading getPaginationByCriteria.", ex);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return beans;
	}

	private void buildQueryForProductSelection(ProductSelection p) {
		if (!StringUtil.isEmptyOrBlank(p.getProductCode())
				|| !StringUtil.isEmptyOrBlank(p.getProductId())
				|| !StringUtil.isEmptyOrBlank(p.getRefcoId())
				|| !StringUtil.isEmptyOrBlank(p.getItemId())
				|| !StringUtil.isEmptyOrBlank(p.getCountryCode())
				|| !StringUtil.isEmptyOrBlank(p.getLanguageCode())) {

			if (!queryString.toString().toLowerCase().contains("where")) {
				append(" WHERE ");
			}
		}

		boolean mustAND = false;

		if (!StringUtil.isEmptyOrBlank(p.getProductCode())) {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "product.productCode" + " LIKE '%"
					+ p.getProductCode() + "%'");
			mustAND = true;
		}

		if (!StringUtil.isEmptyOrBlank(p.getProductId())) {
			try {
				int productId = Integer.parseInt(p.getProductId());
				if (mustAND) {
					append(" AND ");
				}
				append(queryObjChar + "product.productId" + " LIKE '%"
						+ productId + "%'");
				mustAND = true;

			} catch (NumberFormatException ex) {
				LOG.error("Error converting productID string type to int type: ", ex);
			}
		}

		if (!StringUtil.isEmptyOrBlank(p.getRefcoId())) {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "product.commercialReferences.refcoId"
					+ " LIKE '%" + p.getRefcoId() + "%'");
			mustAND = true;
		}

		if (!StringUtil.isEmptyOrBlank(p.getItemId())) {
			try {
				if (mustAND) {
					append(" AND ");
				}
				append(queryObjChar + "itemId" + " LIKE '%" + Long.parseLong(p.getItemId()) + "%'");
				mustAND = true;

			} catch (NumberFormatException ex) {
				LOG.error("Error converting itemID string type to long type: ", ex);
			}
		}
		
		if (!StringUtil.isEmptyOrBlank(p.getCountryCode())) {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "product.commercialReferences.offer.salesSupport.countryCode"
					+ " LIKE '%" + p.getCountryCode() + "%'");
			mustAND = true;
		}

		if (!StringUtil.isEmptyOrBlank(p.getLanguageCode())) {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "product.commercialReferences.offer.salesSupport.languageCode"
					+ " LIKE '%" + p.getLanguageCode() + "%'");
			mustAND = true;
		}

	}

	@Override
	protected Boolean isObject(Field field) {
		return Boolean.FALSE;
	}

	@Override
	protected Object buildCriteria(ProductSelection search) {
		return null;
	}

}
